import React, { Component } from "react";
import PropTypes from "prop-types";
import moment from "moment";
import { DropTarget, DragSource } from "react-dnd";
import { getEmptyImage } from "react-dnd-html5-backend";
import _ from "lodash";

import { MoveType } from "../../constants/constant";
import Event from "../Event/index";
import EmptyEvent from "../Event/emptyEvent";
import { getRandomHexColor, calculateDates, sourceCanDrag } from "../../util/util";

import "./index.scss";

const propTypes = {
  date: PropTypes.object.isRequired,
  today: PropTypes.bool.isRequired,
  moveOption: PropTypes.object.isRequired,
  events: PropTypes.arrayOf(PropTypes.object),
  activeEventId: PropTypes.number.isRequired,
  changeEvent: PropTypes.func,
  changeActiveEventId: PropTypes.func
};

const dropTargetItem = {
  canDrop(props){
    const {canDrop, date} = props;
    return sourceCanDrag(canDrop, props.moveOption.moveType, date);
  }
};

const sourceTarget = {
  beginDrag(props) {
    const { date, changeEvent } = props;

    changeEvent(
      {
        moveType: MoveType.NEW_EVENT,
        originDate: date
      },
      {
        begin: date,
        end: moment(date).endOf("day"),
        color: getRandomHexColor(),
        content: "新建事件"
      }
    );
    return {};
  },
  endDrag(props) {
    const { changeActiveEventId, onDragNewEnd, date, allEvents, activeEventId } = props;
    const event = _.find(allEvents, {id: activeEventId});
    changeActiveEventId(0);
    typeof onDragNewEnd === "function" && onDragNewEnd(date, event);
  },
  canDrag(props){
    const {canDrag, date} = props;
    return sourceCanDrag(canDrag, MoveType.NEW_EVENT, date);
  },
};

@DragSource(MoveType.NEW_EVENT, sourceTarget, (connect, monitor) => ({
  connectDragSource: connect.dragSource(),
  isDragging: monitor.isDragging(),
  dragPreview: connect.dragPreview()
}))
@DropTarget(
  props => props.moveOption.moveType,
  dropTargetItem,
  (connect, monitor) => {
    return {
      connectDropTarget: connect.dropTarget(),
      isOver: monitor.isOver(),
      canElementDrop: monitor.canDrop(), 
    };
  }
)
export default class DayCard extends Component {
  constructor(props) {
    super(props);
    this.renderHeader = this.renderHeader.bind(this);
    this.renderBody = this.renderBody.bind(this);
    this.state = {
      dateFormat: 'Do',
      dateWithMonthFormat: 'MoDo',
    };
  }

  componentDidMount() {
    this.props.dragPreview(getEmptyImage(), {
      captureDraggingState: true
    });
    const locale = moment.locale();
    if(locale.includes('en')){
      this.setState({
        dateFormat: 'DD',
        dateWithMonthFormat: 'MM/DD',
      });
    }
  }

  componentWillReceiveProps(props) {
    const { isOver, activeEventId, moveOption, allEvents, canElementDrop } = props;
    const { date, changeEvent } = this.props;

    if (canElementDrop && isOver && activeEventId && _.some(allEvents, { id: activeEventId })) {
      const event = _.find(allEvents, { id: activeEventId });
      const obj = calculateDates(moveOption, event, date);

      if (
        event.begin.valueOf() === obj.start.valueOf() &&
        event.end.valueOf() === obj.end.valueOf()
      ) {
        return null;
      }

      changeEvent(obj.moveOption, {
        ...event,
        begin: obj.start,
        end: obj.end
      });
    }
  }

  renderHeader() {
    const {date} = this.props;
    let dateString = date.format(this.state.dateFormat);
    if(date.date() === 1){
      dateString = date.format(this.state.dateWithMonthFormat);
    }
    return (
      <div className="rc_day-card-header">{dateString}</div>
    );
  }

  renderBody() {
    const {
      events,
      date,
      changeEvent,
      activeEventId,
      changeActiveEventId,
      moveOption,
      onEventDbClick,
      onDragEnd,
      onEventContextMenu,
      eventTooltip,
      canDrag,
    } = this.props;
    const hasEvents = events && events.length > 0;
    return (
      <div className="rc_day-card-body">
        {hasEvents && (
          <ul className="rc_events-container">
            {events.map((event, index) => {
              if (!event) {
                return <EmptyEvent key={`${date.valueOf()}-empty-${index}`} />;
              }
              return (
                <Event
                  key={`${date.valueOf()}-${event.id}`}
                  event={event}
                  date={date}
                  changeEvent={changeEvent}
                  activeEventId={activeEventId}
                  changeActiveEventId={changeActiveEventId}
                  moveOption={moveOption}
                  onEventDbClick={onEventDbClick}
                  onDragEnd={onDragEnd}
                  onEventContextMenu={onEventContextMenu}
                  eventTooltip={eventTooltip}
                  canDrag={canDrag}
                />
              );
            })}
          </ul>
        )}
      </div>
    );
  }

  render() {
    const {
      className,
      today,
      connectDropTarget,
      connectDragSource,
      onDbClick
    } = this.props;

    return connectDragSource(
      connectDropTarget(
        <div
          className={`rc_day-card ${className || ""} ${
            today ? "rc_today" : ""
          }`}
          onDoubleClick={() => {
            typeof onDbClick === "function" && onDbClick();
          }}
        >
          {this.renderHeader()}
          {this.renderBody()}
        </div>
      )
    );
  }
}

DayCard.propTypes = propTypes;
